
#include <bsp_led_config.h>

#define LED_STATE_OFF   0
#define LED_STATE_ON    1

void (*bsp_led_hal_on_callback)(uint8_t led_num) = 0;
void (*bsp_led_hal_off_callback)(uint8_t led_num) = 0;

typedef struct {
	uint8_t period;
	uint8_t duty_ration;
    uint8_t count;
	uint8_t blink_times;
	uint8_t led_state;
} LED_STRUCT;

static LED_STRUCT LEDS[LED_NUM_MAX];


static void led_struct_init(void) {
    uint8_t i;
    for(i = 0; i < LED_NUM_MAX; i++) {
        LEDS[i].period = 0;
        LEDS[i].duty_ration = 0;
        LEDS[i].count = 0;
		LEDS[i].blink_times = 0;
        LEDS[i].led_state = LED_STATE_OFF;
	}
}


void bsp_led_on(uint8_t led_num)
{
    if(bsp_led_hal_on_callback != 0){
		bsp_led_hal_on_callback(led_num);
    }
    LEDS[led_num].led_state = LED_STATE_ON;
}

void bsp_led_off(uint8_t led_num)
{
    if(bsp_led_hal_off_callback != 0){
		bsp_led_hal_off_callback(led_num);
    }
    LEDS[led_num].led_state = LED_STATE_OFF;
}

void bsp_led_toggle(uint8_t led_num)
{
	if(LEDS[led_num].led_state == LED_STATE_ON){
		bsp_led_off(led_num);
	}
	else{
		bsp_led_on(led_num);
	}
}

uint8_t bsp_led_get_state(uint8_t led_num)
{
    return LEDS[led_num].led_state;
}


//void led_blink_start(void)
//{
//	LEDS[i].led_blink_times = 0;
//}

void bsp_led_blink_stop(uint8_t led_num)
{
	LEDS[led_num].blink_times = 0;
}

uint8_t bsp_led_blink(uint8_t led_num, uint8_t period, 
				uint8_t duty_ration, uint8_t blink_times)
//blink_times = 0xff blink forever
{
	if(duty_ration > period){
		return 0;
	}
	
	if(LEDS[led_num].led_state == LED_STATE_ON){
		bsp_led_off(led_num);
		LEDS[led_num].count = duty_ration;
	}
	else{
		bsp_led_on(led_num);
		LEDS[led_num].count = 0;
	}
	LEDS[led_num].period = period;
	LEDS[led_num].duty_ration = duty_ration;
	LEDS[led_num].blink_times = blink_times;
	return 1;
}

uint8_t bsp_led_is_blink(uint8_t led_num)
{
	return (LEDS[led_num].blink_times == 0)?0:1;
}

uint8_t bsp_led_blink_check_blink_all(void)
{
    uint8_t i;
    for(i = 0; i < LED_NUM_MAX; i++) {
		if(LEDS[i].blink_times != 0){
			return 1;
		}
	}
	return 0;
}


void bsp_led_blink_handler(uint8_t interval_time)
{
    uint8_t i;
    uint16_t temp;

	for (i = 0; i < LED_NUM_MAX; i++) {
        if(LEDS[i].blink_times == 0){
            continue;
        }

		if(LEDS[i].count == 0){
			bsp_led_on(i);
		}

		if(LEDS[i].count == LEDS[i].duty_ration){
			bsp_led_off(i);
			if(LEDS[i].blink_times != 0xff){
				LEDS[i].blink_times--;
			}
		}

		temp = LEDS[i].count + interval_time;
		if(temp >= LEDS[i].period){
			LEDS[i].count = 0;
		}
		else{
			LEDS[i].count = temp;
		}

		if(LEDS[i].blink_times == 0){
			LEDS[i].count = 0;
		}

/*
        if(LEDS[i].led_time_count == 0){
            if(LEDS[i].led_state == LED_STATE_OFF){
                LEDS[i].led_time_count = LEDS[i].led_on_time_set;
                led_on(i);
            }
            else{
                LEDS[i].led_time_count = LEDS[i].led_off_time_set;
                led_off(i);
                LEDS[i].led_blink_times--;
            }
        }
*/
	}
}

void bsp_led_init(void (*bsp_led_hal_init_callback_handler)(void),
				void (*bsp_led_hal_on_callback_handler)(uint8_t led_num),
				void (*bsp_led_hal_off_callback_handler)(uint8_t led_num))
{
	bsp_led_hal_on_callback = bsp_led_hal_on_callback_handler;
	bsp_led_hal_off_callback = bsp_led_hal_off_callback_handler;

    led_struct_init();

    if(bsp_led_hal_init_callback_handler != 0){
		bsp_led_hal_init_callback_handler();
    }
}

/**
void led_test(void)
{
    led_init();
    led_blink(0, 5, 1, 4);
    while(1){
       led_blink_handler();
    }
}
**/
